
#ifndef  HELPER_SCOPE_SCOPABLEADAPTER_H
#define  HELPER_SCOPE_SCOPABLEADAPTER_H

#include <functional>
#include "IScopable.h"

namespace helper {
namespace scope {

template<typename T>
class ScopableAdapter : public IScopable<T>{
public:
    template<typename fnEnter, typename fnExit>
    ScopableAdapter(const fnEnter & enter, const fnExit & exit)
    : funcEnter(enter), funcExit(exit)
    {
    }
    ~ScopableAdapter() override{}
    int enter(T & t) override{
        if(funcEnter){
            funcEnter(t);
            return 0;
        }
        return -1;
    }
    int exit(T & t) override{
        if(funcExit){
            funcExit(t);
            return 0;
        }
        return -1;
    }
private:
    std::function<void (T & t)> funcEnter;
    std::function<void (T & t)> funcExit;
};

template<>
class ScopableAdapter<void> : public IScopable<void> {
public:
    template<typename fnEnter, typename fnExit>
    ScopableAdapter(const fnEnter & enter, const fnExit & exit)
    : funcEnter(enter), funcExit(exit)
    {
    }
    ~ScopableAdapter() override{}
    int enter() override{
        if(funcEnter){
            funcEnter();
            return 0;
        }
        return -1;
    }
    int exit() override{
        if(funcExit){
            funcExit();
            return 0;
        }
        return -1;
    }
private:
    std::function<void (void)> funcEnter;
    std::function<void (void)> funcExit;
};

}// end of namespace scope
}// end of namespace helper

#endif   /* HELPER_SCOPE_SCOPABLEADAPTER_H */
